
<template>
  <div class="test-run-content">
    <div class="test-run-left">
      <p class="test-run-left-title">{{ $t('formSetting.jsCodeBlock.testRunText') }}</p>
      <div class="test-run-form">
        <form-builder
          ref="FormComponent"
          :fields="fields"
          :value="form"
          @update="update"
        >
        </form-builder>
        <div class="send-request">
          <el-button type="primary" class="send-request-button" :disabled="pending" @click="sendRequest">{{ $t('formSetting.jsCodeBlock.testText') }}</el-button>
          <span class="send-request-msg">{{ $t('formSetting.jsCodeBlock.testRunMsg1') }}</span>
        </div>
      </div>
    </div>

    <div class="test-run-right">
      <p class="test-run-right-title">{{ $t('formSetting.jsCodeBlock.jsObject') }}<span :class="[ isSuccess ? 'success': 'fail']" v-if="runResults">{{ isSuccess ? $t('formSetting.jsCodeBlock.parsedSuccess'): $t('formSetting.jsCodeBlock.parsingFailed') }}</span></p>
      <div class="test-run-inforn">
        <div class="test-run-content" v-if="runResults">
          <pre v-html="runResults" class="no-base-tip" v-if="isSuccess"></pre>
          <p class="test-run-error" v-else>{{ runResults }}</p>
        </div>
      </div>
      <p class="test-run-right-msg">{{ $t('formSetting.jsCodeBlock.testRunMsg2') }} </p>
    </div>
  </div>
</template>
<script>
/* vue */
import { defineComponent, toRefs, ref, unref, onMounted, computed } from "vue";
/* util */
import { initialize } from '@src/component/form/util';
import platform from '@src/platform';
import { i18n } from '@src/locales';
import { isObjectString, executeCode, syntaxHighlight, checkJsCode} from '../model/index';
import { uuid } from 'pub-bbx-utils';

export default defineComponent({
  name: 'test-run',
  props: {
    fields: {
      type: Array,
      default: () => ([])
    },
    code: {
      type: String,
      default: () => ''
    },
    analysisResults: {
      type: String,
      default: () => ''
    },
    field: {
      type: Object,
      default: () => ({})
    },
    resultAliasPath: {
      type: Array,
      default: () => [],
    },
  },
  setup(props, { emit }) {
    const { fields, field, code, analysisResults, resultAliasPath } = toRefs(props);
    const pending = ref(false);
    const codeRunResult = ref('');
    // @ts-ignore
    const form = ref(initialize(unref(fields), {}));

    // 初始化数据
    if(analysisResults.value) {
      codeRunResult.value = analysisResults.value;
    }
    /** 是否解析成功*/
    const isSuccess = computed( ()=> {
      return isObjectString(codeRunResult.value);
    });
    /** 运行测试结果*/
    const runResults = computed( ()=> {
      try {
        if(isSuccess.value) return syntaxHighlight(codeRunResult.value);
        return codeRunResult.value;
      }catch (error) {
        console.log(error);
      }
    });
    /** 更新*/
    const update = ({ field, newValue }) => {
      const { fieldName, displayName } = field;
      form.value[fieldName] = newValue;
    };
      /** 测试代码块 */
    const sendRequest = () => {
      // 校验代码块是否有特殊字段
      if(checkJsCode(code.value)){
        return platform.notification({
          title: i18n.t('formSetting.jsCodeBlock.testRunMsg3'),
          message: i18n.t('formSetting.jsCodeBlock.testRunMsg4'),
          type: 'warning',
        });
      }

      codeRunResult.value = executeCode(code.value, form.value, field.value, true);
      // if(isSuccess.value) {
      emit('compilerResult', codeRunResult.value, convertResultAliasPath());
      // }
    };

    /** 生成别名 */
    const convertResultAliasPath = () => {
      if (!isObjectString(codeRunResult.value)) return [];

      const outPutResults = JSON.parse(codeRunResult.value);

      return Object.keys(outPutResults).map(key => {
        const existResultAliasPathItem = resultAliasPath.value.find(item=> item.aliasPath.includes(key));
        if(existResultAliasPathItem) return  { ...existResultAliasPathItem };
        const aliasId = uuid();
        const aliasName = key.length > 50 ? key.substring(0, 50) : key;
        const aliasPath = `$.${key}`;
        const aliasFieldName = field.value.fieldName;

        return { aliasId, aliasName, aliasPath, aliasFieldName };
      });
    };
    return {
      pending,
      codeRunResult,
      form,
      update,
      sendRequest,
      runResults,
      isObjectString,
      isSuccess,
      convertResultAliasPath,
    };
  }
});
</script>
  <style lang="scss" scoped>
  .test-run-content{
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: flex-start;
    .test-run-left{
      margin-right: 16px;
      &-title {
        font-size: 14px;
        color: #262626;
        margin-bottom: 8px;
        font-family: PingFangSC-Medium, PingFang SC;
      }
      &-msg {
        font-size: 14px;
        color: #262626;
      }

      .test-run-form{
        width: 400px;
        height: 400px;
        border: 1px solid #E8E8E8;

        ::v-deep .form-builder{
          padding: 20px 10px;
          height: 340px;
          overflow-y: auto;
          .form-wrap{
            padding: 0;
            .form-item{
                label {
                  width: 70px;
                  @include text-ellipsis();
                }
            }
          }
        }
        .app-nodata-view{
          height: 400px;
        }
        .send-request{
          display: inherit;
          padding-top: 12px;
          border-top: 1px solid  #E8E8E8;
          &-button {
            margin-left:8px;
          }
          &-msg {
            font-size: 12px;
            line-height: 32px;
            margin-left: 8px;
            color: $text-color-secondary;
          }
        }
      }
    }
    .test-run-right{
      width: 320px;
      flex: 1;
      &-title {
        font-size: 14px;
        color: #262626;
        margin-bottom: 8px;
        font-family: PingFangSC-Medium, PingFang SC;
      }
      &-msg {
        font-size: 12px;
        line-height: 20px;
        color: $text-color-secondary;
        margin-top: 8px;
      }
      span{
        margin-left: 8px;
        margin-top: 8px;
      }
      .success {
        color: #67C23A;
      }
      .fail {
        color: #fb4b51;
      }
      .test-run-inforn{
        border: 1px solid #E8E8E8;
        flex: 1;
        height: 343px;
        border-radius: 2px;
        opacity: 1;
      }
      .test-run-error {
        color: #bfbfbf;
        padding: 12px 16px;
        width: 100%;
        overflow: auto;
        margin-bottom: 0;
      }
    }
    ::v-deep pre {
      color: #bfbfbf;
      padding: 12px 16px;
      width: 100%;
      overflow: auto;
      margin-bottom: 0;
      .string{
        color: #10C780;
      }
      .number {
        color: #ED6A0C;
      }
      .boolean {
        color: blue;
      }

      .null {
        color: magenta;
      }
      .key {
        color: #08979C;
      }
    }
  }
  </style>
